export class Type {
  static isBuiltIn(_constructor: any) {
    const built_ins = [
      Object,
      Function,
      Array,
      String,
      Boolean,
      Number,
      Date,
      RegExp,
      Error
    ];

    for (let index = 0; index < built_ins.length; index++) {
      if (_constructor === built_ins[index]) {
        return true;
      }
    }
    return false;
  }
  static string(obj: any) {
    const toString = Object.prototype.toString;
    const stype = toString.call(obj).slice(8, -1);
    if (obj === null || obj == undefined) {
      return stype.toLowerCase();
    }
    var ctype = Type.of(obj);
    if (ctype && !this.isBuiltIn(ctype)) {
      return ctype.name;
    } else {
      return ctype;
    }
  }

  static of(obj: any) {
    if (obj === null || obj == undefined) {
      return obj;
    } else {
      return obj.constructor;
    }
  }

  static is(obj: any, type: any) {
    const typer = (Type.of(type) === "String") ? Type.string : Type.of;
    return typer(obj) === type;
  }

  static instance(obj: any, type: any) {
    return obj instanceof type;
  }
}
